﻿using System;

namespace PicSizer.Program.Algorithm
{
    public class Range
    {
        /// <summary>
        /// 将输入区间[inMin, inMax]内的值映射到输出区间[outMin, outMax]，支持偏差控制
        /// </summary>
        /// <param name="value">输入数值</param>
        /// <param name="inMin">输入区间下限</param>
        /// <param name="inMax">输入区间上限</param>
        /// <param name="outMin">输出区间下限</param>
        /// <param name="outMax">输出区间上限</param>
        /// <param name="bias">偏差系数（0-1），默认0.5</param>
        /// <returns>映射后的数值</returns>
        public static double MapRange(
            double value,
            double inMin, double inMax,
            double outMin, double outMax,
            double bias = 0.5)
        {
            // 检查初始范围
            if (inMin >= inMax || outMin >= outMax)
            {
                throw new ArgumentOutOfRangeException("Invalid range");
            }
            // 检查输入值是否在范围内
            if (value < inMin || value > inMax)
            {
                throw new ArgumentOutOfRangeException("Value out of range");
            }
            // 偏差必须在 0.0 ~ 1.0 (包含) 之间
            if (bias < 0.0 || bias > 1.0)
            {
                throw new ArgumentOutOfRangeException("Bias must be between 0.0 and 1.0");
            }

            // 计算归一化位置（0-1）
            double normalized = (value - inMin) / (inMax - inMin);

            // 应用偏差变换
            double adjusted;
            if (bias == 0.5)
            {
                adjusted = normalized; // 线性映射
            }
            else
            {
                // 非线性变换：使用指数曲线调整分布
                double exponent = Math.Log(bias) / Math.Log(0.5);
                adjusted = Math.Pow(normalized, exponent);
            }

            // 映射到输出范围
            return outMin + adjusted * (outMax - outMin);
        }
    }
}